package br.ufal.ic.p3.darv10.dominio;

import java.util.ArrayList;
import java.util.List;

import br.ufal.ic.p3.darv10.banco.Banco;
import br.ufal.ic.p3.darv10.excecao.DARExcecao;

public class Disciplina {

	private String nomeDisciplina;
	private String codigoDisciplina;
	private int numeroCreditos;
	private boolean isObrigatoria;
	private boolean isOferecida;
	private boolean isGraduacao;
	private int numeroCreditosPreRequisito;
	private List<Disciplina> listaDisciplinasPreRequisito;
	private Professor professorDisciplina;
	private List<Aluno> listaAlunosMatriculados;
	private Curso curso;
	private Secretaria secretaria;


	public Disciplina(){
		setListaAlunosMatriculados(new ArrayList<Aluno>());
		setListaDisciplinasPreRequisito(new ArrayList<Disciplina>());
	}

	public Disciplina(String nomeDisciplina, String codigoDisciplina, int numeroCreditos, boolean isObrigatoria,
			boolean isOferecida, int numeroCreditosPreRequisito, boolean isGraduacao){
		setNomeDisciplina(nomeDisciplina);
		setCodigoDisciplina(codigoDisciplina);
		setNumeroCreditos(numeroCreditos);
		setObrigatoria(isObrigatoria);
		setOferecida(isOferecida);
		setNumeroCreditosPreRequisito(numeroCreditosPreRequisito);
		setListaAlunosMatriculados(new ArrayList<Aluno>());
		setListaDisciplinasPreRequisito(new ArrayList<Disciplina>());
		setIsGraduacao(isGraduacao);
	}

	public void setNomeDisciplina(String nomeDisciplina) {
		this.nomeDisciplina = nomeDisciplina;
	}

	public String getNomeDisciplina() {
		return nomeDisciplina;
	}

	public void setCodigoDisciplina(String codigoDisciplina) {
		this.codigoDisciplina = codigoDisciplina;
	}

	public String getCodigoDisciplina() {
		return codigoDisciplina;
	}

	public void setNumeroCreditos(int numeroCreditos) {
		this.numeroCreditos = numeroCreditos;
	}

	public int getNumeroCreditos() {
		return numeroCreditos;
	}

	public void setObrigatoria(boolean isObrigatoria) {
		this.isObrigatoria = isObrigatoria;
	}

	public boolean isObrigatoria() {
		return isObrigatoria;
	}

	public void setOferecida(boolean isOferecida) {
		this.isOferecida = isOferecida;
	}

	public boolean isOferecida() {
		return isOferecida;
	}

	public void setNumeroCreditosPreRequisito(int numeroCreditosPreRequisito) {
		this.numeroCreditosPreRequisito = numeroCreditosPreRequisito;
	}

	public int getNumeroCreditosPreRequisito() {
		return numeroCreditosPreRequisito;
	}

	public void setListaDisciplinasPreRequisito(
			List<Disciplina> listaDisciplinasPreRequisito) {
		this.listaDisciplinasPreRequisito = listaDisciplinasPreRequisito;
	}

	public List<Disciplina> getListaDisciplinasPreRequisito() {
		return listaDisciplinasPreRequisito;
	}

	public void setProfessorDisciplina(Professor professorDisciplina) {
		this.professorDisciplina = professorDisciplina;
	}

	public Professor getProfessorDisciplina() {
		return professorDisciplina;
	}

	public void setListaAlunosMatriculados(List<Aluno> listaAlunosMatriculados) {
		this.listaAlunosMatriculados = listaAlunosMatriculados;
	}

	public List<Aluno> getListaAlunosMatriculados() {
		return listaAlunosMatriculados;
	}

	public boolean verificaPreRequisito(int numeroCreditos){
		if(numeroCreditos >= numeroCreditosPreRequisito){
			return true;
		}
		else{
			return false;
		}
	}

	public void setIsGraduacao(boolean isGraduacao) {
		this.isGraduacao = isGraduacao;
	}

	public boolean isGraduacao() {
		return isGraduacao;
	}

	public void matricularAluno(Aluno a) throws DARExcecao{

		Curso cursoAluno = a.getCursoAtivo();

		if(!isOferecida()){
			throw new DARExcecao("Disciplina não oferecida no período atual.");
		}

		if(!cursoAluno.isCursoGraduacao() && isGraduacao){
			throw new DARExcecao("Aluno de pós-graduação não pode ser matriculado em um curso de graduação.");
		}

		if((a.getCreditosEletiva() + a.getCreditosObrigatorio()) < numeroCreditosPreRequisito){
			throw new  DARExcecao("O Aluno não possui créditos suficientes para a matrícula.");
		}

		if(cursoAluno.isCursoGraduacao() && !isGraduacao){
			if((a.getCreditosEletiva() + a.getCreditosObrigatorio()) < 170)
				throw new DARExcecao("O Aluno não possui créditos suficientes para a matrícula.");
		}

		if(a.verificaCursandoDisciplina(this)){
			throw new DARExcecao("O aluno já se encontra matriculado nessa disciplina.");
		}

		if(a.verificaDisciplinaCursada(this)){
			throw new DARExcecao("Esse aluno já foi matrículado anteriormente nessa disciplina.");
		}

		if(verificaPreRequisitosAluno(a)){
			throw new DARExcecao("O Aluno não cursou as disciplinas pré-requisitadas.");
		}

		listaAlunosMatriculados.add(a);
		a.adicionarDisciplinaJaCursada(this);

	}

	public boolean verificaPreRequisitosAluno(Aluno a){

		boolean condicaoParaMatricula = false;

		for(Disciplina d : listaDisciplinasPreRequisito){
			if(a.verificaDisciplinaCursada(d)){
				condicaoParaMatricula = true;
			}
		}

		return condicaoParaMatricula;
	}

	public String toString(){
		return nomeDisciplina;
	}

	public List<Disciplina> getDisciplinasBD() throws DARExcecao {
		Banco bd = Banco.getInstance();
		return bd.getDisciplinas();
	}

	public void setCurso(Curso curso) {
		this.curso = curso;
	}

	public Curso getCurso() {
		return curso;
	}

	public void setSecretaria(Secretaria secretaria) {
		this.secretaria = secretaria;
	}

	public Secretaria getSecretaria() {
		return secretaria;
	}
	
	public void adicionarPreReqDisciplina(Disciplina d){
		listaDisciplinasPreRequisito.add(d);
	}

}